package buff

import (
	"encoding/binary"
	"encoding/hex"
	"math"
)

type Buffer struct {
	Endian binary.ByteOrder
	Buf    []byte
	end    int
	
	pos int // 存进去字节游标

	outPos int // 取出来的字节游标
}


// func: NewBuffer(size int) *Buffer 
// aim: 小标头字节封装

func NewBuffer(size int) *Buffer {
	return &Buffer{Buf: make([]byte, size), Endian: binary.LittleEndian, end: size}
}

func NewBufferBytes(Buf []byte) *Buffer {
	return &Buffer{Buf: Buf, Endian: binary.LittleEndian, end: len(Buf)}
}

// 更改存进数据游标
func (this *Buffer) UpdatePos(pos int)  {
	this.pos += pos
}

// 更改取出字节的游标
func (this *Buffer) UpdateOutPos(outPos int)  {
	this.outPos += outPos
}

func (this *Buffer) UpdateOutPosUtils(outPos int)  {
	this.outPos = outPos
}

func (this *Buffer) Hex(pos, num int) string {
	end := pos + num
	if pos > this.end {
		return ""
	}
	if end > this.end {
		end = this.end
	}
	return hex.EncodeToString(this.Buf[pos:end])
}

func (this *Buffer) Length() int {
	return this.end
}

//重新设置为新数据
func (this *Buffer) ResetData(Buf []byte) {
	this.end = len(Buf)
	if this.end > len(this.Buf) {
		this.Buf = make([]byte, this.end)
	}
	copy(this.Buf, Buf)
}

func (this *Buffer) Clear() {
	this.end = 0
}

func (this *Buffer) Limit(end int) {
	if len(this.Buf) > end {
		this.end = end
	}
}

func (this *Buffer) Bytes() []byte {
	return this.Buf
}



// func: (this *Buffer) PutByte(value byte)
// aim: 放一个字节，游标移动1

func (this *Buffer) PutByte(value byte) {
	this.Buf[this.pos] = value
	this.UpdatePos(1)
	return
}
func (this *Buffer) Byte() (value byte) {
	value = this.Buf[this.outPos]
	this.UpdateOutPos(1)
	return
}


// func: (this *Buffer) PutUint16(pos int, value uint16) 
// aim: 放 uint16 , 游标移动2

func (this *Buffer) PutUint16(value uint16) {
	this.Endian.PutUint16(this.Buf[this.pos:], value)
	this.UpdatePos(2)
	return
}


// func: (this *Buffer) Uint16(pos int) (value uint16)
// aim: 取出Uint16

func (this *Buffer) Uint16(pos int) (value uint16) {
	value = this.Endian.Uint16(this.Buf[this.outPos:])
	this.UpdateOutPos(2)
	return
}


// func: (this *Buffer) PutUint32(pos int, value uint32)
// aim: 放uint32 , 游标移动4

func (this *Buffer) PutUint32(value uint32) {
	this.Endian.PutUint32(this.Buf[this.pos:], value)
	this.UpdatePos(4)
	return
}


// func: (this *Buffer) Uint32() (value uint32)
// aim: 取出Uint32, 字节4

func (this *Buffer) Uint32() (value uint32) {
	value = this.Endian.Uint32(this.Buf[this.outPos:])
	this.UpdateOutPos(4)
	return
}


// func: (this *Buffer)PutUint64(value uint64)
// aim: 放uint64, 8字节

func (this *Buffer)PutUint64(value uint64)  {
	this.Endian.PutUint64(this.Buf[this.pos:], value)
	this.UpdatePos(8)
	return
}


// func: (this *Buffer)Uint64() (value uint64)
// aim: 取出Uint64, 8 字节

func (this *Buffer)Uint64() (value uint64) {
	value = this.Endian.Uint64(this.Buf[this.outPos:])
	this.UpdateOutPos(8)
	return
}

// func: (this *Buffer) PutFloat(pos int, value float32) 
// aim: uint32, 4字节

func (this *Buffer) PutFloat(value float32) {
	this.Endian.PutUint32(this.Buf[this.pos:], math.Float32bits(value))
	this.UpdatePos(4)
	return
}


// func: (this *Buffer) Float32() float32
// aim: 取出float32, 实质是Uint32

func (this *Buffer) Float32() float32 {
	val := this.Endian.Uint32(this.Buf[this.outPos:])
	this.UpdateOutPos(4)
	return math.Float32frombits(val)
}


// func: (this *Buffer)PutFloat64(value uint64)
// aim: float64就是内部放的uint64， 8字节

func (this *Buffer)PutFloat64(value float64)  {
	this.Endian.PutUint64(this.Buf[this.pos:], math.Float64bits(value))
	this.UpdatePos(8)
	return
}


// func: (this *Buffer)Float64() float64
// aim: 取出float64, 实质是Uint64

func (this *Buffer)Float64() float64 {
	val := this.Endian.Uint64(this.Buf[this.outPos:])
	this.UpdateOutPos(8)
	return math.Float64frombits(val)
}


// func: (this *Buffer)PutInt16(value int16)
// aim: 放int16, 实质是PutUint16

func (this *Buffer)PutInt16(value int16)  {
	this.Endian.PutUint16(this.Buf[this.pos:], uint16(value))
	this.UpdatePos(2)
	return
}


// func: (this *Buffer)Int`6() int`6
// aim: 取出int16, 实质是实质是PutUint16

func (this *Buffer)Int16() int16 {
	val := this.Endian.Uint16(this.Buf[this.outPos:])
	this.UpdateOutPos(2)
	return int16(val)
}


// func: (this *Buffer)PutInt(value int)
// aim: 放int, 实质是PutUint32

func (this *Buffer)PutInt(value int)  {
	this.Endian.PutUint32(this.Buf[this.pos:], uint32(value))
	this.UpdatePos(4)
	return
}


// func: (this *Buffer)Int() int
// aim: 取出int, 实质是实质是PutUint32

func (this *Buffer)Int() int {
	val := this.Endian.Uint32(this.Buf[this.outPos:])
	this.UpdateOutPos(4)
	return int(val)
}


// func: (this *Buffer)PutInt64(value int64)
// aim: 放int64, 实质是PutUint64

func (this *Buffer)PutInt64(value int64)  {
	this.Endian.PutUint64(this.Buf[this.pos:], uint64(value))
	this.UpdatePos(8)
	return
}


// func: (this *Buffer)Int64() int64
// aim: 取出int64, 实质是实质是PutUint64

func (this *Buffer)Int64() int64 {
	val := this.Endian.Uint32(this.Buf[this.outPos:])
	this.UpdateOutPos(8)
	return int64(val)
}

func (this *Buffer) PutArray(value []byte) {
	copy(this.Buf[this.pos:], value)
	this.UpdatePos(len(value))
	return
}

func (this *Buffer) Array(size int) []byte {
	data :=  this.Buf[this.outPos : this.outPos+size]
	this.UpdateOutPos(size)
	return data
}


// func:  (this *Buffer) LastArray() []byte
// aim: 获取剩余字节数

func (this *Buffer) LastArray() []byte {
	data := this.Buf[this.outPos:]
	return data
}

// func: (this *Buffer)PutHook(h Hook)
// aim: hook

type Hook func(Buf *Buffer)

func (this *Buffer)PutHook(h Hook)  {
	h(this)
}